package com.hhsjdesign.dynamicui.utils


import java.lang.Exception
import java.util.HashMap

/**
 * class缓存池
 */
object ClassCachePool {
    //组件
    const val WIDGET = 0

    //业务数据
    const val BUSINESS_BEAN = 1

    //组件数据对象
    const val WIDGET_DATA = 2

    //组件属性类
    const val WIDGET_PROPERTY = 3

    //组件视图处理类
    const val VIEW_HOLDER = 4

    //组件数据获取类
    const val BUSINESS_CALLER = 5

    //组件ITEM数据模型类
    const val WIDGET_ITEM_DATA = 6

    /**
     * 获取类文件
     *
     * @param type       类的类型
     * @param widgetType 类的标志
     * @return
     */
    fun getClassByWidgetType(type: Int, widgetType: String): Class<*>? {
        return when (type) {
            WIDGET -> WidgetPool.getClassByWidgetType(widgetType)
            BUSINESS_BEAN -> BusinessBeanPool.getClassByWidgetType(widgetType)
            WIDGET_DATA -> WidgetDataPool.getClassByWidgetType(widgetType)
            WIDGET_PROPERTY -> WidgetPropertyPool.getClassByWidgetType(widgetType)
            VIEW_HOLDER -> ViewHolderPool.getClassByWidgetType(widgetType)
            BUSINESS_CALLER -> BusinessCallerPool.getClassByWidgetType(widgetType)
            WIDGET_ITEM_DATA -> WidgetItemDataPool.getClassByWidgetType(widgetType)
            else -> {
                WidgetPool.getClassByWidgetType(widgetType)
            }
        }
    }

    fun dataCallerSize(): Int {
        return WidgetDataPool.classNameMap.size
    }

    fun viewHolderSize(): Int {
        return ViewHolderPool.classNameMap.size
    }

    fun businessDataSize(): Int {
        return BusinessBeanPool.classNameMap.size
    }

    fun init(config: DynamicUIConfig) {
        for ((key, value) in config.businessBeanTypeList()) {
            BusinessBeanPool.inject(key, value)
        }
        for ((key, value) in config.viewHolderTypeList()) {
            ViewHolderPool.inject(key, value)
        }
        for ((key, value) in config.dataCallerTypeList()) {
            BusinessCallerPool.inject(key, value)
        }
        for ((key, value) in config.widgetViewTypeList()) {
            WidgetPool.inject(key, value)
        }
        for ((key, value) in config.widgetPropertyTypeList()) {
            WidgetPropertyPool.inject(key, value)
        }
        for ((key, value) in config.widgetDataTypeList()) {
            WidgetDataPool.inject(key, value)
        }
        for ((key, value) in config.widgetItemViewTypeList()) {
            WidgetItemDataPool.inject(key, value)
        }
    }

    internal object WidgetPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object BusinessBeanPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object WidgetDataPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object WidgetPropertyPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object ViewHolderPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object BusinessCallerPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

    internal object WidgetItemDataPool {
        //class object
        var cachePool: MutableMap<String, Class<*>> = HashMap()

        //class name
        private var classNameMap: MutableMap<String, String> = HashMap()
        fun getClassByWidgetType(widgetType: String): Class<*>? {
            if (cachePool[widgetType] != null && classNameMap[widgetType] != null) {
                return cachePool[widgetType]!!
            }
            var clazz: Class<*>? = null
            classNameMap[widgetType]?.let {
                try {
                    clazz = Class.forName(it)
                    clazz?.let { c ->
                        cachePool[widgetType] = c
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    cachePool.remove(widgetType)
                }
            }
            return clazz
        }

        fun inject(key: String?, value: String?) {
            if (key == null || value == null || "" == key || "" == value) {
                return
            }
            classNameMap[key] = value
        }
    }

}